<template>
  <a-modal v-model:open="visible" title="分配权限" ok-text="保存" cancel-text="取消" :confirm-loading="saveLoading" @ok="handleSave" @cancel="close">
    <Tree v-model:checked-keys="checkedKeys" checkable :tree-data="treeData" check-strictly @check="onChecked" />
  </a-modal>
</template>

<script setup>
import { Tree } from 'ant-design-vue'

const visible = ref(false)
const treeData = ref([])
const checkedKeys = ref({ checked: [], halfChecked: [] })
const saveLoading = ref(false)
let roleId = ''

// 打开权限分配弹窗
function open(id) {
  roleId = id
  visible.value = true
  // Fetch permissions for the role
  fetchPermissions(id)
}

// 获取权限数据
async function fetchPermissions(id) {
  const data = await httpRequest(`/admin/role/permissions`, { id })
  treeData.value = data.treeData
  checkedKeys.value.checked = data.selectedKeys
}

function checkChild(checkedList, children, checked) {
  children.forEach(child => {
    if (child.children) {
      checkChild(checkedList, child.children, checked)
    }
    if (checked) {
      checkedList.push(child.id)
    }
    else {
      const index = checkedList.findIndex(id => id == child.id)
      if (index >= 0) {
        checkedList.splice(index, 1)
      }
    }
  })
}

// 选中事件
function onChecked(obj, { node, checked }) {
  if (node.children) {
    checkChild(obj.checked, node.children, checked)
  }
  if (checked && node.parentId) {
    const parentIndex = obj.checked.findIndex(id => id == node.parentId)
    if (parentIndex < 0) {
      node.parent.nodes.forEach(parent => obj.checked.push(parent.id))
    }
  }
}

// 保存权限分配
async function handleSave() {
  saveLoading.value = true
  try {
    await httpRequest(`/admin/role/assignPermissions`, {
      roleId,
      permissions: checkedKeys.value.checked,
    })
    message.success('权限分配成功')
    saveLoading.value = false
    visible.value = false
  }
  catch (error) {
    saveLoading.value = false
  }
}

function close() {
  visible.value = false
  treeData.value = []
  checkedKeys.value = []
}

defineExpose({ open })
</script>

<style scoped></style>
